﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

using WcfCore;

namespace WcfClientHost
{
	public class HostInfo
	{
		public HostInfo(string inputFilename, string machineName, string exePath)
		{
			InputFilename = inputFilename;
			MachineName = machineName;
			ExePath = exePath;
		}

		public HostInfo(string inputFilename, string machineName, string exePath, string username, string password)
			: this(inputFilename, machineName, exePath)
		{
			Username = username;
			Password = password;
		}

		public string InputFilename;
		public string MachineName;
		public string Username;
		public string Password;
		public string ExePath;
		public string ProcessName
		{
			get
			{
				return Path.GetFileName(ExePath);
			}
		}
	}

	public class HostWrapper : IDisposable
	{
		public HostWrapper(HostInfo host, string psExecExePath, string psKillExePath)
		{
			_host = host;
			PsExecExePath = psExecExePath;
			PsKillExePath = psKillExePath;

			string commandline;
			if (Host.Username == null)
			{
				commandline = Host.InputFilename;
				CallGenericProcess(Host.ExePath, commandline, false);
			}
			else
			{
				commandline = string.Format(@"-d \\{0} -u {1} -p {2} {3} {4}",
					Host.MachineName,
					Host.Username,
					Host.Password,
					Host.ExePath,
					Host.InputFilename);
				CallPsExec(commandline);
			}
		}

		private readonly HostInfo _host;
		public HostInfo Host
		{
			get
			{
				return _host;
			}
		}

		public string ServiceTypeName;
		public string PsExecExePath;
		public string PsKillExePath;

		#region IDisposable Members
		private bool _disposed;
		private void Dispose(bool disposing)
		{
			if (_disposed)
			{
				return;
			}

			if (disposing)
			{
				// Cleanup managed
			}

			// Cleanup unmanaged
			KillHosts();

			_disposed = true;
		}

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		~HostWrapper()
		{
			Dispose(false);
		}
		#endregion

		private void CallGenericProcess(string exePath, string commandline, bool waitForExit)
		{
			Process psexec = new Process();
			psexec.StartInfo = new ProcessStartInfo(exePath, commandline);
			psexec.Start();
			if (waitForExit)
			{
				psexec.WaitForExit();
			}
		}

		private void CallPsExec(string commandline)
		{
			Process psexec = new Process();
			psexec.StartInfo = new ProcessStartInfo(PsExecExePath, commandline);
			psexec.Start();
			psexec.WaitForExit();
		}

		private void KillHosts()
		{
			for (int i = 0; i < 2; i++)
			{
				string commandline;
				if (Host.Username != null)
				{
					commandline = string.Format(@"-t \\{0} -u {1} -p {2} {3}", Host.MachineName, Host.Username, Host.Password, Host.ProcessName);
				}
				else
				{
					commandline = string.Format(@"-t {0}", Host.ProcessName);
				}

                WcfProcessHelper.StartChildProcessAndWaitForExit(PsKillExePath, commandline);
			}
		}
	}
}
